﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;
using System.IO;
using System.Xml;
using System.Workflow.Runtime;

namespace OpenComposite.Repository.Tracking
{
	internal class TrackedProcessInstance
	{
		#region Initialization

		public TrackedProcessInstance()
		{
		}

		public TrackedProcessInstance(TrackingWorkflowInstance instance)
		{
			this.Instance = instance;
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		public string AssemblyFullName
		{
			get;
			set;
		}

		public DateTime EndTime
		{
			get
			{
				if ( Instance.ActivityEvents.Count != 0 ) return Instance.ActivityEvents[Instance.ActivityEvents.Count - 1].EventDateTime;
				return Instance.Initialized;
			}
		}

		public TrackingWorkflowInstance Instance
		{
			get;
			private set;
		}

		public string Name
		{
			get
			{
				if ( Instance != null && Instance.WorkflowType != null ) return Instance.WorkflowType.Name;
				if ( !string.IsNullOrEmpty(Instance.WorkflowTypeName) ) return Instance.WorkflowTypeName.Substring(Instance.WorkflowTypeName.LastIndexOf('.') + 1);
				return "(empty)";
			}
		}

		public DateTime StartTime
		{
			get
			{
				if ( Instance.ActivityEvents.Count != 0 ) return Instance.ActivityEvents[0].EventDateTime;
				return Instance.Initialized;
			}
		}

		public WorkflowStatus Status
		{
			get { return Instance.Status; }
		}

		public string ToolTip
		{
			get
			{
				return string.Format("First event at: {1}{0}Last event at:{2}",
					Environment.NewLine, StartTime, EndTime);
			}
		}

		public string TypeFullName
		{
			get;
			set;
		}

		public Activity Workflow
		{
			get
			{
				if ( string.IsNullOrEmpty(this.WorkflowDefinition) ) return null;
				if ( _workflow == null ) {
					WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
					try {
						using ( StringReader sr = new StringReader(this.WorkflowDefinition) )
						using ( XmlReader xr = XmlReader.Create(sr) ) {
							_workflow = serializer.Deserialize(xr) as Activity;
						}
					} catch { return null; }
				}
				return _workflow;
			}
		}

		public string WorkflowDefinition
		{
			get;
			set;
		}

		public Type WorkflowType
		{
			get
			{
				if ( _type == null ) {
					_type = Type.GetType(TypeFullName + ", " + AssemblyFullName, false, false);
				}
				return _type;
			}
		}

		#endregion Properties

		#endregion Public Members

		#region Private Members

		#region Fields

		private Type _type = null;
		private Activity _workflow = null;

		#endregion Fields

		#endregion Private Members
	} 
}
